home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 2001-2002 Raven Software, Inc.
- //
- // cg_weaponinit.c -- weapon initialization
-
- #include "cg_local.h"
- #include "../game/bg_weapons.h"
-
- // FIMXE: This is defined in a C++ header file.
- // We need to break it up or somethin so we don't have mutliple defs.
- #define GHOUL2_NORENDER 2
-
- /*
- =================
- CG_RegisterItemVisuals
-
- The server says this item is used on this level
- =================
- */
- void CG_RegisterItemVisuals( int itemNum )
- {
- itemInfo_t *itemInfo;
- gitem_t *item;
- char simpleName[MAX_QPATH];
-
- if ( itemNum < 0 || itemNum >= bg_numItems )
- {
- Com_Error( ERR_FATAL, "CG_RegisterItemVisuals: itemNum %d out of range [0-%d]", itemNum, bg_numItems-1 );
- }
-
- itemInfo = &cg_items[ itemNum ];
- if ( itemInfo->registered )
- {
- return;
- }
-
- item = &bg_itemlist[ itemNum ];
-
- memset( itemInfo, 0, sizeof( &itemInfo ) );
- itemInfo->registered = qtrue;
-
- itemInfo->models[0] = trap_R_RegisterModel( item->world_model[0] );
-
- // Check to see if its a ghoul model we loaded
- if (!Q_stricmp(&item->world_model[0][strlen(item->world_model[0]) - 4], ".glm"))
- {
- trap_G2API_InitGhoul2Model(&itemInfo->g2Models[0], item->world_model[0], 0 , 0, 0, 0, 0);
- itemInfo->radius[0] = 60;
-
- // Special case to make sure some sufaces are show that should be
- switch ( item->giTag )
- {
- case WP_AK74_ASSAULT_RIFLE:
- trap_G2API_SetSurfaceOnOff( itemInfo->g2Models[0], 0, "bayonet_off", 0 );
- break;
-
- case WP_M4_ASSAULT_RIFLE:
- trap_G2API_SetSurfaceOnOff( itemInfo->g2Models[0], 0, "m203_off", 0 );
- break;
- }
- }
-
- itemInfo->icon = trap_R_RegisterShaderNoMip( item->icon );
-
- if (item->icon[0])
- {
- Com_sprintf(simpleName, sizeof(simpleName), "%s_simple", item->icon);
- itemInfo->mSimpleIcon = trap_R_RegisterShader(simpleName);
- }
- else
- {
- itemInfo->mSimpleIcon = 0;
- }
-
-
- if ( item->giType == IT_WEAPON )
- {
- CG_RegisterWeapon( item->giTag );
- }
- }
-
- /*
- =================
- CG_RegisterWeapon
-
- The server says this item is used on this level
- =================
- */
- void CG_RegisterWeapon(int weaponNum)
- {
- weaponInfo_t *weaponInfo;
- weaponData_t *weaponDat;
- TWeaponModel *weaponModel;
- TOptionalWeapon *optionalPart;
- gitem_t *item,*ammo;
- TWeaponParseInfo *wPI;
- int weaponIndex; // model index for view weapon models
- int bufferIndex; // weapon + buffer + rhand [+ lhand ]
- int rHandIndex;
- int lHandIndex;
- int boltonIndex;
- int boltIndex;
- int soundSet, i;
- int *indexes;
-
- if(weaponNum==0)
- {
- return;
- }
-
- boltonIndex = -1;
-
- assert(weaponNum < WP_NUM_WEAPONS);
-
- weaponInfo=&cg_weapons[weaponNum];
- if(weaponInfo->registered)
- {
- return;
- }
-
- memset(weaponInfo,0,sizeof(*weaponInfo));
-
- // Register the item visuals (icons etc).
- weaponInfo->item = item = BG_FindWeaponItem ( weaponNum );
-
- // Must be initial loading
- if ( !weaponInfo->registered )
- {
- CG_LoadingItem( item - bg_itemlist );
- }
-
- // Ok, successfully registered the entire weapon.
- weaponInfo->registered=qtrue;
-
- weaponDat = &weaponData[weaponNum];
-
- if(item->classname)
- {
- // Hmmm... this needs some work... some of it looks if now.
- CG_RegisterItemVisuals( item - bg_itemlist );
- }
- else
- {
- Com_Error( ERR_FATAL, "CG_RegisterWeapon: Couldn't find weapon item %i", weaponNum);
- }
-
- // Register the weapon's world ammo model.
- for ( ammo = bg_itemlist + 1 ; ammo->classname ; ammo++ )
- {
- if ( ammo->giType == IT_AMMO && ammo->giTag == weaponNum )
- {
- break;
- }
- }
-
- if( ammo->classname && ammo->world_model[0] )
- {
- trap_G2API_InitGhoul2Model(&weaponInfo->ammoG2Model,ammo->world_model[0],0,0,0,0,0);
- }
-
- // Create the world model.
- weaponIndex = trap_G2API_InitGhoul2Model(&weaponInfo->weaponG2Model,weaponDat->worldModel,0,0,0,0,0);
- if(!trap_G2_HaveWeGhoul2Models(weaponInfo->weaponG2Model))
- {
- Com_Printf("CG_RegisterWeapon: Unable to load weapon world model: %s\n", weaponDat->worldModel);
- }
-
- // Register the weapon model...
- indexes=weaponInfo->viewG2Indexes;
- for(i=0;i<8;i++)
- {
- indexes[i]=-1;
- }
-
- wPI=&weaponParseInfo[weaponNum];
-
- // Create the view weapon model in slot 0.
- indexes[0] = weaponIndex = trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
- wPI->mWeaponModel.mModel,0,0,0,0,0);
-
- // Now build and assemble all the other bits.
- if(trap_G2_HaveWeGhoul2Models(weaponInfo->viewG2Model))
- {
- // Add a bolt to the weapon so buffer can be bolted on.
- boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,weaponIndex,wPI->mWeaponModel.mBufferBoltToBone);
-
- // Every view weapon has a buffer, create this in slot 1.
- indexes[1]=bufferIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
- wPI->mWeaponModel.mBufferModel,
- weaponIndex+1,0,0,0,0);
- // Bolt the buffer to the weapon.
- trap_G2API_AttachG2Model(weaponInfo->viewG2Model,bufferIndex,
- weaponInfo->viewG2Model,boltIndex,weaponIndex);
-
- // Right hand??
- if(wPI->mWeaponModel.mRightHandsBoltToBone[0])
- {
- // Add a right hand bolt to the buffer.
- boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
- wPI->mWeaponModel.mRightHandsBoltToBone);
-
- // Right hand.. create this now in slot 2.
- indexes[2]=rHandIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
- "models/weapons/rhand/rhand.glm",
- weaponIndex+2,0,0,0,0);
-
- // Bolt the right hand to the buffer.
- trap_G2API_AttachG2Model(weaponInfo->viewG2Model,rHandIndex,weaponInfo->viewG2Model,
- boltIndex,bufferIndex);
- }
-
- // Left hand??
- if(wPI->mWeaponModel.mLeftHandsBoltToBone[0])
- {
- // Add a left hand bolt to the buffer.
- boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
- wPI->mWeaponModel.mLeftHandsBoltToBone);
-
- // Left hand.. create this now in slot 3.
- indexes[3]=lHandIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
- "models/weapons/lhand/lhand.glm",
- weaponIndex+3,0,0,0,0);
-
- // Bolt the left hand to the buffer.
- trap_G2API_AttachG2Model(weaponInfo->viewG2Model,lHandIndex,weaponInfo->viewG2Model,
- boltIndex,bufferIndex);
- }
-
- // Boltons like the M4's grenade launcher?
- if(wPI->mWeaponModel.mBolton)
- {
- // Add a bolton bolt to the buffer.
- boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
- wPI->mWeaponModel.mBolton->mBoltToBone);
-
- // Bolton.. create this now in slot 4.
- indexes[4]=boltonIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
- wPI->mWeaponModel.mBolton->mModel,
- weaponIndex+4,0,0,0,0);
- // Bolt the bolton to the buffer.
- if ( boltonIndex != -1 )
- {
- trap_G2API_AttachG2Model(weaponInfo->viewG2Model,boltonIndex,weaponInfo->viewG2Model,
- boltIndex,bufferIndex);
- }
- }
-
- // Turn of any weapon surfaces that are never seen.
- weaponModel=&wPI->mWeaponModel;
- i=0;
- while(weaponModel->mRightSideSurfaces[i])
- {
- trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
- weaponModel->mRightSideSurfaces[i],GHOUL2_NORENDER);
- i++;
- }
- i=0;
- while(weaponModel->mFrontSurfaces[i])
- {
- trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
- weaponModel->mFrontSurfaces[i],GHOUL2_NORENDER);
- i++;
- }
- if(weaponModel->mBolton && boltonIndex != -1 )
- {
- i=0;
- while(weaponModel->mBolton->mRightSide[i])
- {
- trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,boltonIndex,
- weaponModel->mBolton->mRightSide[i],GHOUL2_NORENDER);
- i++;
- }
- }
-
- // Turn off optional parts as we don't want em.
- optionalPart=weaponModel->mOptionalList;
- while(optionalPart)
- {
- // No real way of knowing what single player intended so we have to
- // hard-code 'em.
- if((!strcmp(optionalPart->mName,"lasersight"))||
- (!strcmp(optionalPart->mName,"silencer"))||
- (!strcmp(optionalPart->mName,"utl")))
- {
- i=0;
- while(optionalPart->mSurfaces[i])
- {
- trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
- optionalPart->mSurfaces[i],GHOUL2_NORENDER);
- i++;
- }
- }
- optionalPart=optionalPart->mNext;
- }
- }
- else
- {
- Com_Printf("CG_RegisterWeapon: Unable to load weapon view model: %s\n", wPI->mWeaponModel.mModel);
- }
-
- weaponInfo->attack[ATTACK_NORMAL].missileTrailFunc = CG_ProjectileThink;
- weaponInfo->attack[ATTACK_ALTERNATE].missileTrailFunc = CG_ProjectileThink;
-
- // Register weapon list menu icons.
- if (weaponDat->menuImage[0])
- {
- weaponInfo->weaponIcon = trap_R_RegisterShader( va( "gfx/menus/%s", weaponDat->menuImage) );
- }
-
- // Register the alternate weapon ammo icon for the hud
- if (weaponDat->attack[ATTACK_ALTERNATE].icon[0] )
- {
- weaponInfo->attack[ATTACK_ALTERNATE].ammoIcon = trap_R_RegisterShader( va( "gfx/menus/%s", weaponDat->attack[ATTACK_ALTERNATE].icon ) );
- }
-
- // Register attack stuff
- for ( i = ATTACK_NORMAL; i < ATTACK_MAX; i ++ )
- {
- attackData_t* attackData = &weaponDat->attack[i];
- attackInfo_t* attackInfo = &weaponInfo->attack[i];
-
- // Primary muzzle-flash.
- if (attackData->muzzleEffect[0])
- attackInfo->muzzleEffect = trap_FX_RegisterEffect(attackData->muzzleEffect);
- if (attackData->muzzleEffectInWorld[0])
- attackInfo->muzzleEffectInWorld = trap_FX_RegisterEffect(attackData->muzzleEffectInWorld);
- if (!attackInfo->muzzleEffectInWorld)
- attackInfo->muzzleEffectInWorld = attackInfo->muzzleEffect;
-
- // Primary shell eject.
- if (attackData->shellEject[0])
- attackInfo->shellEject = trap_FX_RegisterEffect(attackData->shellEject);
- if (attackData->tracerEffect[0])
- attackInfo->tracerEffect = trap_FX_RegisterEffect(attackData->tracerEffect);
-
- // Primary explosion.
- if (attackData->explosionEffect[0])
- attackInfo->explosionEffect = trap_FX_RegisterEffect(attackData->explosionEffect);
- if (attackData->explosionSound[0])
- attackInfo->explosionSound = trap_S_RegisterSound(attackData->explosionSound);
- if (attackData->missileG2Model[0])
- trap_G2API_InitGhoul2Model(&attackInfo->missileG2Model,attackData->missileG2Model,0,0,0,0,0);
-
- // Add the bolts for muzzle flash and shell eject onto the view model.
- if (trap_G2_HaveWeGhoul2Models(weaponInfo->viewG2Model))
- {
- // shell eject bone.
- if ( attackData->ejectBone[0] )
- {
- attackInfo->shellEjectBoltView =
- trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, attackData->ejectBone);
- }
-
- // Muzzle flash bone.
- attackInfo->muzzleFlashBoltView = -1;
- if(attackData->muzzleEffect[0])
- {
- if ( attackData->muzzleEffectBone[0] )
- {
- attackInfo->muzzleFlashBoltView =
- trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, attackData->muzzleEffectBone );
- }
- else if (wPI->mWeaponModel.mBufferMuzzle[0])
- {
- attackInfo->muzzleFlashBoltView =
- trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, wPI->mWeaponModel.mBufferMuzzle);
- }
- }
- }
-
- // Add the bolts for muzzle flash and shell eject onto the world model.
- if (trap_G2_HaveWeGhoul2Models(weaponInfo->weaponG2Model))
- {
- // shell eject bone.
- if (attackData->ejectBone[0])
- {
- attackInfo->shellEjectBoltWorld =
- trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, attackData->ejectBone);
- }
- else
- {
- attackInfo->shellEjectBoltWorld = -1;
- }
-
- // Muzzle flash bone.
- attackInfo->muzzleFlashBoltWorld = -1;
- if ( attackData->muzzleEffectBone[0] )
- {
- attackInfo->muzzleFlashBoltWorld =
- trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, attackData->muzzleEffectBone );
- }
- else if (wPI->mWeaponModel.mBufferMuzzle[0])
- {
- attackInfo->muzzleFlashBoltWorld =
- trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, wPI->mWeaponModel.mBufferMuzzle);
- }
- }
- }
-
- // Register sounds for weapon.
- for (soundSet = 0; soundSet < MAX_WEAPON_SOUNDS; soundSet++)
- {
- if (Q_stricmp(wPI->mSoundNames[soundSet], "fire")==0)
- {
- for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
- {
- if (wPI->mSounds[soundSet][i][0])
- {
- weaponInfo->attack[ATTACK_NORMAL].flashSound[i] = trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
- }
- }
- }
- else if (Q_stricmp(wPI->mSoundNames[soundSet], "altfire")==0)
- {
- for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
- {
- if (wPI->mSounds[soundSet][i][0])
- weaponInfo->attack[ATTACK_ALTERNATE].flashSound[i] = trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
- }
- }
- else
- {
- // All other sounds.
- for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
- {
- if (wPI->mSounds[soundSet][i][0])
- weaponInfo->otherWeaponSounds[soundSet][i]=trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
- }
- }
- }
-
- // Special hard coded stuff
- switch ( weaponNum )
- {
- case WP_KNIFE:
- {
- attackInfo_t* attackInfo = &weaponInfo->attack[ATTACK_ALTERNATE];
- attackInfo->missileSound = trap_S_RegisterSound ( "sound/weapons/knife/throw_loop" );
- break;
- }
-
- case WP_RPG7_LAUNCHER:
- {
- attackInfo_t* attackInfo = &weaponInfo->attack[ATTACK_NORMAL];
- attackInfo->missileSound = trap_S_RegisterSound ( "sound/weapons/rpg7/flyby" );
- break;
- }
- }
- }
-
- /*
- =================
- CG_ShutDownWeapons
-
- Clean out any g2 models
- =================
- */
- void CG_ShutDownWeapons ( void )
- {
- int i;
- attackType_t a;
-
- for (i=0; i < WP_NUM_WEAPONS; i++)
- {
- // free all ghoul2 models
- trap_G2API_CleanGhoul2Models(&cg_weapons[i].weaponG2Model);
- trap_G2API_CleanGhoul2Models(&cg_weapons[i].viewG2Model);
- trap_G2API_CleanGhoul2Models(&cg_weapons[i].ammoG2Model);
-
- for ( a = ATTACK_NORMAL; a < ATTACK_MAX; a ++ )
- {
- trap_G2API_CleanGhoul2Models(&cg_weapons[i].attack[a].missileG2Model);
- }
- }
- }
-